package com.yesep.learn.design.behavioral.mediator;

import com.yesep.learn.design.common.*;

/**
 * 中介者模式（Mediator Pattern）是一种对象行为型模式，主要用于降低系统中对象之间的耦合度，通过引入一个中介者来封装对象之间的交互，使得对象之间的交互更加灵活和可扩展。
 * 以下是关于中介者模式的详细解析：
 * <p>
 * 一、定义与原理
 * 定义：中介者模式定义了一个中介对象来封装一系列对象之间的交互，使原有对象之间的耦合松散，且可以独立地改变它们之间的交互。
 * 中介者模式又叫调停模式，是迪米特法则（最少知识原则）的典型应用。
 * <p>
 * 原理：在中介者模式中，各个对象不再直接相互引用和通信，而是通过中介者来进行间接通信。
 * 这样，对象之间的交互就被封装在中介者中，降低了对象之间的耦合度，提高了系统的灵活性和可维护性。
 * <p>
 * 二、结构与角色
 * 中介者模式主要包含以下几个角色：
 * <p>
 * 抽象中介者（Mediator）：定义了中介者的接口，提供了同事对象注册与转发同事对象信息的抽象方法。
 * 具体中介者（ConcreteMediator）：实现中介者接口，定义一个集合来管理同事对象，协调各个同事角色之间的交互关系。
 * 同事接口（Colleague）：定义了同事类的接口，保存中介者对象，并实现同事类的公共方法。同事类之间不直接通信，而是通过中介者来通信。
 * 具体同事类（ConcreteColleague）：实现同事接口，并在需要与其他同事通信时，通过中介者来间接通信。
 * 三、优点
 * 降低了对象之间的耦合度：通过引入中介者，对象之间的直接引用被中介者所取代，降低了对象之间的耦合度。
 * 提高了系统的灵活性和可扩展性：由于对象之间的交互被封装在中介者中，因此可以独立地改变对象之间的交互方式，而不需要修改对象本身的代码。
 * 简化了对象之间的交互：用中介者和同事的一对多交换替代了原来的同事之间的多对多交换，简化了对象之间的交互关系。
 * 易于维护：当系统需要增加新的同事类时，只需要在中介者中添加对该同事类的支持即可，而不需要修改其他同事类的代码。
 * 四、缺点
 * 中介者逻辑可能变得复杂：如果系统中存在大量的同事类，并且它们之间的交互关系复杂，那么中介者的逻辑可能会变得非常复杂，难以维护。
 * 可能导致系统难以调试：由于对象之间的交互被封装在中介者中，因此在调试时可能需要跟踪中介者的内部状态，增加了调试的难度。
 * 五、应用场景
 * 中介者模式适用于以下场景：
 * <p>
 * 系统中对象之间存在复杂的引用关系，系统结构混乱且难以理解。
 * 一个对象由于引用了其他很多对象并且直接和这些对象通信，导致难以复用该对象。
 * 需要通过一个中间类来封装多个类中的行为，但又不想生成太多的子类。
 * 在MVC（Model-View-Controller）框架中，控制器（Controller）可以作为模型（Model）和视图（View）之间的中介者，协调它们之间的通信。
 * 六、实例
 * 以QQ游戏中的欢乐斗地主为例，可以引入一个中介者对象来协调各个玩家之间的金币交换。
 * 每个玩家在赢得金币时，不再直接修改其他玩家的金币数量，而是通过中介者来完成金币的转移。
 * 这样，即使某个玩家的金币计算逻辑出现问题，也不会影响到其他玩家的状态，从而降低了系统之间的耦合度。
 */
public class Main {
    public static void main(String[] args) {
        String dogName = AnimalType.Dog.name(), catName = AnimalType.Cat.name(), beeName = AnimalType.Bee.name();
        IMediator mediator = new ConcreteMediator();
        IColleague dog = new ConcreteColleague(dogName);
        IColleague cat = new ConcreteColleague(catName);
        IColleague bee = new ConcreteColleague(beeName);
        mediator.register(dog);
        mediator.register(cat);
        mediator.register(bee);

        dog.send(catName, "晚上出来吃饭，叫上" + beeName);
        cat.send(beeName, dogName + "叫咱一起吃饭");
        bee.send(catName, "收到，老地方见");
        bee.send(dogName, catName + "和我说了，老地方见");
    }
}
